package com.cskt.petproject178.service.third;

import com.cskt.petproject178.config.OrderDelayQueueConfig;
import com.cskt.petproject178.config.WeChatPayAutoConfigProperties;
import com.cskt.petproject178.mapper.OrderMapper;
import com.cskt.petproject178.pojo.entity.Comment;
import com.cskt.petproject178.pojo.entity.Order;
import com.cskt.petproject178.pojo.exception.BaseException;
import com.cskt.petproject178.pojo.vo.OrderDetailVO;
import com.cskt.petproject178.pojo.vo.StatusEnum;
import com.cskt.petproject178.util.Constant;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.ecommercerefund.model.CreateRefundRequest;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.Status;
import jakarta.annotation.Resource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.swing.table.TableRowSorter;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 微信支付servic层
 *
 * @author 27013
 **/

@Service
public class WeChatPayService {
    private static final Logger log = LogManager.getLogger(WeChatPayService.class);
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private RSAAutoCertificateConfig config;
    @Resource
    private WeChatPayAutoConfigProperties properties;
    @Resource
    private AmqpTemplate amqpTemplate;


    public String codeUrl(String orderNo){
        //初始化native支付service
        NativePayService nativePayService = new NativePayService.Builder()
                .config(config)
                .build();
        //准备相应的参数
        PrepayRequest request = new PrepayRequest();
    //先根据订单号查询对应的订单获取相关的信息
        OrderDetailVO orderDetailVO = orderMapper.selectOrderDetailVOByOrderNo(orderNo);
        //判断订单状态
        if (ObjectUtils.isEmpty(orderDetailVO)) {
            log.warn("当前订单不存在:orderNo{}",orderNo);
            throw new BaseException(StatusEnum.ORDER_NOT_EXIST);
        }
        //判断订单状态 必须是待支付 ，以及支付状态必须是未支付
        if (!orderDetailVO.getOrderStatus().equals(Constant.OrderStatus.PENDING_PAYMENT) || !orderDetailVO.getPayStatus().equals(Constant.PayStatus.UNPAID)) {
            log.warn("当前订单状态异常，orderNo:{},orderStatus:{},payStatus:{}",orderNo,orderDetailVO.getOrderStatus(),orderDetailVO.getPayStatus());
            throw new BaseException(StatusEnum.ORDER_STATUS_ERROR);
        }
        request.setAppid(properties.getAppId());
        request.setMchid(properties.getMerchantId());
        request.setOutTradeNo(orderNo);
        //支付总金额（必须已分为单位）
        Amount amount = new Amount();
        amount.setTotal(orderDetailVO.getPayMoney().multiply(BigDecimal.valueOf(100)).intValue());
        amount.setCurrency("CNY");
       request.setAmount(amount);
       request.setDescription("宠爱有家-"+orderNo);
       request.setNotifyUrl(properties.getNotifyUrl());
       //发起请求，获取code_url
        PrepayResponse response = nativePayService.prepay(request);
        log.info("微信支付生成二维码响应结果：{}",response);
        String codeUrl = response.getCodeUrl();
        return codeUrl;
    }

    /**
     * 申请退款
     */
    public void refund(String orderNo){
        Order order = orderMapper.selectOrderByOrderNo(orderNo);
        RefundService service = new RefundService.Builder()
                .config(config).build();
        CreateRequest createRequest = new CreateRequest();
        AmountReq amount = new AmountReq();
        //退款金额（必须已分为单位）
        long totalMoeny = order.getTotalMoney().multiply(BigDecimal.valueOf(100)).longValue();
        //退款金额要和订单总金额一致
        amount.setRefund(totalMoeny);
        amount.setTotal(totalMoeny);
        amount.setCurrency("CNY");
        createRequest.setAmount(amount);
        createRequest.setOutTradeNo(orderNo);
        createRequest.setOutRefundNo(orderNo);
        Refund refund = service.create(createRequest);
        log.info("微信退款响应结果：{}",refund);
        Status status = refund.getStatus();
        switch (status){
            case SUCCESS -> {
                log.info("微信退款成功，订单号：{}",orderNo);
            }
        }


    }

    /**
     * 微信支付回调
     * @param body
     * @param serialNumber
     * @param signature
     * @param signType
     * @param nonce
     * @param timestamp
     */



    public void wechatPayCallback(String body,String serialNumber,String signature,String signType,String nonce,String timestamp){
        RequestParam requestParam = new RequestParam.Builder()
                //回调参数中的请求体
                .body(body)
                //序列号
                .serialNumber(serialNumber)
                //应答的微信支付签名
                .signature(signature)

                .signType(signType)
                //签名中的随机数
                .nonce(nonce)
                ////签名中的时间戳
                .timestamp(timestamp)
                .build();
        //效验回调数据是否合法
        NotificationParser parser = new NotificationParser(config);
        Transaction transaction = parser.parse(requestParam, Transaction.class);
        //获取交易状态--微信定义的支付状态
        Transaction.TradeStateEnum tradeState = transaction.getTradeState();
        //从校验中取出订单号
        Order order = orderMapper.selectOrderByOrderNo(transaction.getOutTradeNo());
        //判断订单状态
        if (ObjectUtils.isEmpty(order)) {
            log.warn("当前订单不存在:orderNo{}",order.getOrderNo());
            throw new BaseException(StatusEnum.ORDER_NOT_EXIST);
        }
        //判断订单状态 必须是待支付 ，以及支付状态必须是未支付
        if (!order.getOrderStatus().equals(Constant.OrderStatus.PENDING_PAYMENT) || !order.getPayStatus().equals(Constant.PayStatus.UNPAID)) {
            log.warn("当前订单状态异常，orderNo:{},orderStatus:{},payStatus:{}",order.getOrderNo(),order.getOrderStatus(),order.getPayStatus());
            throw new BaseException(StatusEnum.ORDER_STATUS_ERROR);
        }
        // 针对微信定义的不同状态做出相应的处理
        switch (tradeState){
            //支付成功，修改订单状态为成功
            case SUCCESS -> {
                log.info("微信支付成功，订单号：{}",order.getOrderNo());
                //修改订单状态为已支付
                order.setPayStatus(Constant.PayStatus.PAYMENT_SUCCESS);
                LocalDateTime payTime = LocalDateTime.parse(transaction.getSuccessTime(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
                order.setPayTime(payTime);
                //修改订单状态为待发货
                order.setOrderStatus(Constant.OrderStatus.TO_BE_SHIPPED);
            }
            //支付状态已关闭
            case CLOSED -> {
                log.info("微信支付已关闭，订单号：{}",order.getOrderNo());
            }
            //支付状态已退款
            case REFUND -> {
                log.info("微信支已退款，订单号：{}",order.getOrderNo());
                //修改订单状态为退款
                order.setPayStatus(Constant.PayStatus.PAYMENT_FAIL);
            }
            //支付状态未支付
            case NOTPAY -> {
                log.info("微信未支付，订单号：{}",order.getOrderNo());
                order.setPayStatus(Constant.PayStatus.PAYMENT_FAIL);
            }
        }
        order.setUpdatedTime(LocalDateTime.now());
        //执行最后的修改
        orderMapper.updateByPrimaryKeySelective(order);
    }



}
